#!/bin/bash

# AddressSanitizer 内存泄漏检测脚本
# 使用环境变量配置 ASan，在程序终止时也能生成报告

echo "======================================"
echo "ASan 内存泄漏检测工具"
echo "======================================"

# 检查编译是否启用了 ASan
if [ ! -f "build/bin/server_test" ]; then
    echo "错误: 找不到 build/bin/server_test"
    echo "请先编译项目: cd build && cmake -G Ninja .. && ninja"
    exit 1
fi

# 创建日志目录
LOG_DIR="asan_logs"
mkdir -p $LOG_DIR

# 配置 ASan 选项
export ASAN_OPTIONS="halt_on_error=0:detect_leaks=1:log_path=${LOG_DIR}/asan_log.txt:exitcode=0:fast_unwind_on_malloc=0"

# 显示配置
echo -e "\n[ASan 配置]"
echo "日志目录: $LOG_DIR"
echo "ASan选项: $ASAN_OPTIONS"
echo ""
echo "配置说明:"
echo "  - halt_on_error=0      : 遇到错误不立即停止，继续运行"
echo "  - detect_leaks=1       : 启用内存泄漏检测"
echo "  - log_path             : 日志文件路径"
echo "  - exitcode=0           : 即使检测到问题也返回0"
echo "  - fast_unwind_on_malloc=0 : 更准确的堆栈跟踪（稍慢）"

# 询问运行方式
echo -e "\n选择运行方式:"
echo "1. 手动测试 (启动后自行运行客户端，按 Ctrl+C 停止)"
echo "2. 定时测试 (运行指定秒数后自动停止)"
read -p "请选择 (1/2): " choice

case $choice in
    1)
        echo -e "\n启动服务器..."
        echo "按 Ctrl+C 停止服务器"
        cd build/bin
        ./server_test
        ;;
    2)
        read -p "运行多少秒后自动停止? [60]: " duration
        duration=${duration:-60}
        echo -e "\n启动服务器，将在 ${duration} 秒后自动停止..."

        cd build/bin
        ./server_test &
        SERVER_PID=$!

        echo "服务器 PID: $SERVER_PID"
        echo "运行时间倒计时: ${duration}s"

        # 倒计时显示
        for ((i=$duration; i>0; i--)); do
            echo -ne "\r剩余时间: ${i}s "
            sleep 1
        done

        echo -e "\n\n发送终止信号..."
        kill -TERM $SERVER_PID 2>/dev/null
        wait $SERVER_PID 2>/dev/null
        ;;
    *)
        echo "无效选择"
        exit 1
        ;;
esac

# 返回项目根目录
cd ../..

# 检查并显示报告
echo -e "\n======================================"
echo "检测完成，正在分析报告..."
echo "======================================"

if [ -z "$(ls -A $LOG_DIR 2>/dev/null)" ]; then
    echo "✓ 未生成 ASan 日志文件，可能没有检测到内存问题"
    echo "  (如果服务器运行正常但没有日志，这是好消息)"
else
    echo -e "\n找到以下日志文件:"
    ls -lh $LOG_DIR/

    echo -e "\n=== 内存泄漏摘要 ==="
    for log in $LOG_DIR/asan_log.txt.*; do
        if [ -f "$log" ]; then
            echo -e "\n文件: $log"
            # 提取泄漏摘要
            if grep -q "ERROR: LeakSanitizer" "$log"; then
                echo "🔴 检测到内存泄漏:"
                grep -A 5 "Direct leak\|Indirect leak" "$log" | head -20
            elif grep -q "ERROR: AddressSanitizer" "$log"; then
                echo "🔴 检测到内存错误:"
                grep "ERROR: AddressSanitizer" "$log"
            else
                echo "✓ 此日志无明显错误"
            fi
        fi
    done

    echo -e "\n详细报告位于: $LOG_DIR/"
    echo "查看完整报告: cat $LOG_DIR/asan_log.txt.*"
fi

echo -e "\n检测结束"
